// 获取画布对象
const canvas = document.getElementById("canvas");
const content = canvas.getContext("2d");

// 小球半径
const radius = 10;
// 小球坐标信息
let ballPos = { x: canvas.width / 2, y: canvas.height / 2 };
// 小球运动速度
let speedX = 2;
let speedY = 1;

// 挡板高度
const panelHeight = 50;

// 挡板添加阴影效果
content.shadowBlur = 1;
content.shadowOffsetY = 2;
content.shadowOffsetX = 2;
content.shadowColor = "grey";

// 加载材质对象
let panelPattern = "white"; // 挡板材质填充对象 默认白色
const img = document.getElementById("mood");
img.onload = function () {
    panelPattern = content.createPattern(img, "no-repeat");
}

// 游戏名称 渲染
function randerGameName() {
    content.font = "oblique 600 20px STHeiti"; // 设置字体样式
    // 文本居中
    const txtWidth = content.measureText("小游戏").width;
    const txtHeight = content.measureText("M").width;
    const xpos = (canvas.width - txtWidth) / 2;
    const ypos = (canvas.height - txtHeight) / 2;
    const grd = content.createLinearGradient(0, ypos, 0, ypos + txtHeight); // 从上至下渐变
    grd.addColorStop(0, "red"); // 添加渐变颜色点
    grd.addColorStop(0.5, "white");
    grd.addColorStop(1, "yellow");
    content.fillStyle = grd;
    content.textBaseline = "top"; // 设置文本绘制基线，让文本上下居中
    content.fillText("小游戏", xpos, (canvas.height - txtHeight) / 2);
}

function drawPanel(content,x,y,pat,height){
    content.fillStyle = pat;
    content.fillRect(x,y,5,height);
}

// 渲染分隔线
function renderLine(){
    content.strokeStyle = "black";
    content.lineWidth = 1;
    const posX = canvas.width / 2;
    let posY = 0,
        set = new Set();
    for (let i = 0; ; i++) {
        if (i % 2) continue;
        posY = i * 10;
        const y = posY;
        set.add(() => {
            // console.log(`posY=${y}`);
            content.moveTo(posX, y);
            content.lineTo(posX, y + 10);
            //drawLine(content, posX, y);
        });
        if (posY > canvas.height) break;
    }
    content.beginPath();
    for (let f of set) f();
    content.stroke();
}

function render() {
    // 绘制背景
    content.fillStyle = "whitesmoke";
    content.fillRect(0, 0, canvas.width, canvas.height);
    randerGameName();
    // 绘制右挡板
    drawPanel(content, canvas.width -5, rightPanelY, panelPattern, panelHeight);
    // 绘制左挡板
    drawPanel(content, 0, leftPanelY, panelPattern, panelHeight);
    // 渲染分隔线
    renderLine();
    // 根据小球位置绘制
    content.fillStyle = "white";
    content.beginPath();
    content.arc(ballPos.x, ballPos.y, radius, 0, 2 * Math.PI);
    content.fill();
    // 渲染分数
    content.font = "100 12px STHeiti";
    content.fillStyle = "yellow";
    content.shadowOffSetX = content.shadowOffsetY = 0;
    drawText(content,10,canvas.height - 20, "玩家：" + userScore);
    let sysScoreText = "系统：" + systemScore;
    drawText(content,canvas.width - 20 - content.measureText(sysScoreText).width,canvas.height - 20,sysScoreText);
    drawBgMusicButton();
}

function drawText(content, x, y, text) {
    content.fillText(text,x,y);
}

// 左挡板变化数据
let leftPanelY = { x: canvas.width / 2, y: canvas.height / 2 }; // 左挡板的起点Y坐标
// 监听鼠标移动事件
canvas.addEventListener("mousemove", function (e) {
    let y = e.clientY - canvas.getBoundingClientRect().top - panelHeight / 2;
    if (y > 0 && y < (canvas.height - panelHeight)) { // 溢出检测
        leftPanelY = y;
    }
});

// 小球与墙壁四周的碰撞检查
function testHitWall() {
    // 碰到右边界
    if (ballPos.x > canvas.width - radius) {
        speedX = -speedX;
    }
    // 碰到左边界
    if (ballPos.x < radius) {
        speedX = -speedX;
    }
    // 碰到右边界
    if (ballPos.y > canvas.height - radius) {
        speedY = -speedY;
    }
    // 碰到左边界
    if (ballPos.y < radius) {
        speedY = -speedY;
    }
}

// 右挡板变化数据
const rightPanelMoveRange = 50; // 设置右挡板上下移动数值范围
let rightPanelY = (canvas.height - panelHeight); // 开始位置居中
let rightPanelSpeedY = 0.5; // 移动速度

function run() {
    // 清屏
    content.clearRect(0,0,canvas.width,canvas.height);
    // 碰撞检测
    testHitPanel();
    testHitWall();
    // 计算小球位置
    ballPos.x += speedX;
    ballPos.y += speedY;
    // 右挡板运动数据计算
    rightPanelY += rightPanelSpeedY;
    const centerY = (canvas.height - panelHeight) / 2;
    if (rightPanelY < (centerY - rightPanelMoveRange) || rightPanelY > (centerY + rightPanelMoveRange)) {
        rightPanelSpeedY = -rightPanelSpeedY;
    }
    // 渲染
    render();
    if(!gameOver) {
         requestAnimationFrame(run);
    } else {
        const text = "游戏结束";
        content.font = "800 26px STHeiti";
        content.fillStyle = "black";
        content.textBaseline = "middle";
        content.clearRect(0,0,canvas.width,canvas.height);
        drawText(content,canvas.width / 2 - content.measureText(text).width / 2, canvas.height / 2,text);
        const restartTip = "点击屏幕重新开始";
        content.font = "12px FangSong";
        content.fillStyle = "gray";
        drawText(content,canvas.width / 2 - content.measureText(restartTip).width / 2, canvas.height / 2 + 25, restartTip);
        
        canvas.addEventListener("click",onClickScreenWhileGameOver);
        stopBGAudio();
    }
}

// 重启游戏
function onClickScreenWhileGameOver(e){
    playHitAudio();
    // 移除监听
    canvas.removeEventListener("click",onClickScreenWhileGameOver);
    // 重设分数信息
    userScore = 0;
    systemScore = 0;
    gameOver = false;

    // 重设小球位置
    ballPos = { x: canvas.width / 2, y: canvas.height / 2 }
    run();
    playBGAudio();
}

// function playHitAudio() {
//     const hitAudio = document.getElementById("hit-sound");
//     hitAudio.play();
// }

function playHitAudio(){
    const audio = new Audio("hit-sound");
    if (audio.canPlayType("audio/mp3")){
        audio.src = "./click5.mp3";
    }
    if (audio.canPlayType("audio/ogg")) {
        audio.src = "./click5.ogg";
    }
    audio.play();
}

// 背景音乐
const bgAudio = new Audio("bg-sound");
if (bgAudio.canPlayType("audio/ogg")) {
    bgAudio.src = "./bg.ogg"
} 
// else if (audio.canPlayType("audit/mp3")){
//     bgAudio.src = "./bg.mp3";
// }

function playBGAudio() {
    bgAudio.currentTime=0;
    bgAudio.play();
}

function stopBGAudio() {
    bgAudio.pause();
}

// 绘制音乐按钮
function drawBgMusicButton(){
    const btnCanvas = document.createElement("canvas");
    btnCanvas.width = 48;
    btnCanvas.height = 48;
    const btnContext = btnCanvas.getContext("2d");
    let bgMusicIsPlaying = bgAudio.currentTime > 0 && !bgAudio.paused
    if (bgMusicIsPlaying) {
        const musicBtnOnImg = new Image();
        musicBtnOnImg.src = "./on-sound.png";
        btnContext.fillStyle = content.createPattern(musicBtnOnImg,"no-repeat");
    } else {
        const musicBtnOffImg = new Image();
        musicBtnOffImg.src = "./off-sound.png";
        btnContext.fillStyle = content.createPattern(musicBtnOffImg,"no-repeat");
    }
    btnContext.fillRect(0,0,48,48);
    content.drawImage(btnCanvas,0,0,48,48,5,5,15,15)
}

// function drawBgMusicButton() {
//     const img = new Image();
//     let bgMusicIsPlaying = bgAudio.currentTime > 0 && !bgAudio.paused
//     if (bgMusicIsPlaying) {
//         img.src = "./on-sound.png";
//     } else {
//         img.src = "./off-sound.png";
//     }
//     content.drawImage(img,0,0,48,48,5,5,15,15);
// }

canvas.addEventListener("click",function(e) {
    const pos = { x: e.offsetX,y: e.offsetY };
    if (pos.x > 5 && pos.x < 53 && pos.y > 5 && pos.y < 53) {
        console.log("单击了背景音乐按钮");
        const bgMusicIsPlaying = bgAudio.currentTime > 0 && !bgAudio.paused
        bgMusicIsPlaying ? stopBGAudio() : playBGAudio();
    }
});

// 计分
let userScore = 0, systemScore = 0; // 玩家分数 系统分数
let gameOver = false; // 游戏是否结束

// 检测挡板碰撞
function testHitPanel() {
    // 碰撞右挡板
    if (ballPos.x > (canvas.width - radius - 5)) {
        if (ballPos.y > rightPanelY && ballPos.y < (rightPanelY + panelHeight)) {
            speedX = -speedX;
            console.log("碰撞右挡板");
            systemScore ++;
            console.log(`systemScore:{$systemScore}`);
            checkScore();
            playHitAudio();
        }
    } else 
    // 碰撞左挡板
    if (ballPos.x < radius + 5){
        if (ballPos.y > leftPanelY && ballPos.y < (leftPanelY + panelHeight)){
            speedX = -speedX;
            console.log("碰撞左挡板");
            userScore ++;
            console.log(`userScore:{$userScore}`);
            checkScore();
            playHitAudio();
        }
    }
}

function checkScore(){
    if (systemScore >= 3 || userScore >= 1) {
        gameOver = true;
        console.log("游戏结束:`{$userScore} - {$systemScore}`");
    }
}

run();
playBGAudio();